<?php

namespace App\Http\Controllers\Admin;

use App\Exports\AfterSaleCompensationExport;
use App\Exports\CultivationAwardExport;
use App\Exports\DailyReportStatisticsExport;
use App\Exports\FinanceDetailsExport;
use App\Exports\ProfitStatisticsExport;
use App\Http\Controllers\Controller;
use App\Models\AgentRevenue;
use App\Models\AgentReward;
use App\Models\CommodityActivity;
use App\Models\CommodityActivitySkuStatistics;
use App\Models\DailyReportStatistics;
use App\Models\SummaryBase;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Symfony\Component\HttpKernel\Exception\HttpException;

class FinanceController extends Controller
{
    /**
     * 商品利润统计
     * @param Request $request
     * @return mixed
     */
    public function profitStatistics(Request $request)
    {
        if ($request->has('export')) {
            return (new ProfitStatisticsExport($request))->download(sprintf('利润统计(%s).xls', Carbon::now()->format('YmdHisu')));
        }

        return $this->response->array(
            CommodityActivitySkuStatistics::query()
                ->join('commodities', 'commodities.id', '=', 'commodity_activity_sku_statistics.commodity_id')
                ->join('commodity_activities', 'commodity_activities.id', '=', 'commodity_activity_sku_statistics.commodity_activity_id')
                ->join('suppliers', 'suppliers.id', '=', 'commodities.supplier_id')
                ->with('commodityActivitySku.values')
                ->when($request->get('numbering'), function (Builder $builder, $numbering) {
                    $builder->where('commodities.numbering', 'like', "$numbering%");
                })
                ->when($request->get('activity_numbering'), function (Builder $builder, $activityNumber) {
                    $builder->where('commodity_activities.numbering', 'like', "$activityNumber%");
                })
                ->when($request->get('commodity_name'), function (Builder $builder, $name) {
                    $builder->where('commodities.name', 'like', "$name%");
                })
                ->when($request->get('supplier_name'), function (Builder $builder, $supplierName) {
                    $builder->where('suppliers.name', 'like', "$supplierName%");
                })
                ->when($request->get('created_at_begin'), function (Builder $builder, $createdAtBegin) {
                    $builder->where('commodities.created_at', '>=', $createdAtBegin);
                })
                ->when($request->get('created_at_end'), function (Builder $builder, $createdAtEnd) {
                    $builder->where('commodities.created_at', '<=', Carbon::parse($createdAtEnd)->endOfDay());
                })
                ->when($request->get('panic_buying_start_time') && $request->get('panic_buying_end_time'), function (Builder $builder) use ($request) {
                    $betweenArr = [
                        Carbon::parse($request->get('panic_buying_start_time'))->startOfDay()->format('Y-m-d H:i:s'),
                        Carbon::parse($request->get('panic_buying_end_time'))->endOfDay()->format('Y-m-d H:i:s')
                    ];
                    $builder->whereBetween('commodity_activities.panic_buying_start_time', $betweenArr);
                })
                ->select([
                    'commodity_activity_sku_statistics.*',
                    'commodities.numbering',
                    'commodities.created_at as commodity_created_at',
                    'commodities.name as commodity_name',
                    'commodity_activities.numbering as commodity_activity_numbering',
                    'commodity_activities.panic_buying_start_time',
                    'commodity_activities.panic_buying_end_time',
                    'suppliers.name as supplier_name',
                ])
                ->paginate()
        );
    }

    /**
     * 每日报表
     * @param Request $request
     * @return mixed
     */
    public function dailyReportStatistics(Request $request)
    {
        if ($request->has('export')) {
            return (new DailyReportStatisticsExport($request))->download(sprintf('每日报表(%s).xls', Carbon::now()->format('YmdHisu')));
        }

        return $this->response->array(
            DailyReportStatistics::query()
                ->when($request->get('date'), function (Builder $builder, $date) {
                    $builder->where('date', $date);
                })
                ->paginate()
        );
    }

    /**
     * 每日下单奖励
     * @param Request $request
     * @return mixed
     */
    public function dailyRewardList(Request $request)
    {
        return $this->response->array(
            AgentReward::query()
                ->with(['agent'])
                ->where('type', AgentReward::TYPE_DAILY_ORDER_REWARD)
                ->when($request->get('status', AgentReward::STATUS_PENDING_REVIEW), function (Builder $builder, $status) {
                    $builder->where('status', $status);
                })
                ->when($request->get('date_begin'), function (Builder $builder, $date) {
                    $builder->where('date', '>=', $date);
                })
                ->when($request->get('date_end'), function (Builder $builder, $date) {
                    $builder->where('date', '<=', $date);
                })
                ->paginate()
        );
    }

    /**
     * 审批发放每日下单奖励
     * @param Request $request
     */
    public function approvalOfDailyAwards(Request $request)
    {
        $ids = $request->get('ids');
        if (empty($ids)) {
            throw new HttpException(400, 'ID 不能为空');
        }
        try {
            \DB::beginTransaction();

            $daily = AgentReward::query()
                ->with(['source', 'agent'])
                ->where('type', AgentReward::TYPE_DAILY_ORDER_REWARD)
                ->where('status', AgentReward::STATUS_PENDING_REVIEW)
                ->whereIn('id', $ids)
                ->get();
            if ($daily->isEmpty()) {
                $this->response->errorBadRequest('没有需要审核的奖励');
            }
            foreach ($daily as $item) {
                // 当日的业绩是否还满足
                $dailySummary = $item->agent
                    ->dailySummary()
                    ->where([
                        'day' => $item['award_date'],
                        'type' => SummaryBase::TYPE_AGENT
                    ])
                    ->first(); // 当日业绩统计
                if (empty($dailySummary)) {
                    $this->response->errorBadRequest('获取当日下单金额失败');
                }
                if ($dailySummary['performance_summary'] < $item['threshold_amount']) {
                    $this->response->errorBadRequest('当日下单金额已经不达标');
                }
                // 发放奖励
                $item->agent->incrementOrDecrementBalance($item['reward'], AgentRevenue::TYPE_DAILY_ORDER_REWARD, $item['source'], 'increment', Carbon::parse($item['award_date']));
            }

            // 变更状态
            AgentReward::query()
                ->whereIn('id', $daily->pluck('id'))
                ->update([
                    'remark' => $request->get('remark', ''),
                    'status' => AgentReward::STATUS_PASSED,
                    'operator_id' => \Auth::id()
                ]);

            \DB::commit();
        } catch (\Exception $e) {
            \DB::rollBack();
            $this->response->errorBadRequest($e->getMessage());
        }

        return $this->response->noContent();
    }

    /**
     * 每月活动奖励
     * @param Request $request
     * @return mixed
     */
    public function monthlyRewardList(Request $request)
    {
        return $this->response->array(
            AgentReward::query()
                ->with(['agent'])
                ->where('type', AgentReward::TYPE_MONTHLY_ORDER_REWARD)
                ->when($request->get('status', AgentReward::STATUS_PENDING_REVIEW), function (Builder $builder, $status) {
                    $builder->where('status', $status);
                })
                ->when($request->get('begin_month'), function (Builder $builder, $date) {
                    $builder->where('award_date', '>=', Carbon::parse($date)->startOfMonth());
                })
                ->when($request->get('end_month'), function (Builder $builder, $date) {
                    $builder->where('award_date', '<=', Carbon::parse($date)->endOfMonth());
                })
                ->paginate()
        );
    }

    /**
     * 审批发放每月活动奖励
     * @param Request $request
     * @return \Dingo\Api\Http\Response
     */
    public function approvalOfMonthlyAwards(Request $request)
    {
        $ids = $request->get('ids');
        if (empty($ids)) {
            throw new HttpException(400, 'ID 不能为空');
        }
        try {
            \DB::beginTransaction();

            $monthly = AgentReward::query()
                ->with(['source', 'agent'])
                ->where('type', AgentReward::TYPE_MONTHLY_ORDER_REWARD)
                ->where('status', AgentReward::STATUS_PENDING_REVIEW)
                ->whereIn('id', $ids)
                ->get();
            if ($monthly->isEmpty()) {
                $this->response->errorBadRequest('没有需要审核的奖励');
            }
            foreach ($monthly as $item) {
                // 当月的业绩是否还满足
                $monthlySummary = $item->agent
                    ->monthlySummary()
                    ->where([
                        'month' => Carbon::parse($item['award_date'])->format('Ym'),
                        'type' => SummaryBase::TYPE_AGENT
                    ])
                    ->first(); // 当日业绩统计
                if (empty($monthlySummary)) {
                    $this->response->errorBadRequest('获取当日下单金额失败');
                }
                if ($monthlySummary['performance_summary'] < $item['threshold_amount']) {
                    $this->response->errorBadRequest('当日下单金额已经不达标');
                }
                // 发放奖励
                $item->agent->incrementOrDecrementBalance($item['reward'], AgentRevenue::TYPE_ORDER_REWARD_PER_MONTH, $item['source'], 'increment', Carbon::parse($item['award_date']));
            }

            // 变更状态
            AgentReward::query()
                ->whereIn('id', $monthly->pluck('id'))
                ->update([
                    'remark' => $request->get('remark', ''),
                    'status' => AgentReward::STATUS_PASSED,
                    'operator_id' => \Auth::id()
                ]);

            \DB::commit();
        } catch (\Exception $e) {
            \DB::rollBack();
            $this->response->errorBadRequest($e->getMessage());
        }

        return $this->response->noContent();
    }

    /**
     * 培养奖
     * @param Request $request
     * @return mixed
     */
    public function getCultivationAward(Request $request)
    {
        if ($request->has('export')) {
            return (new CultivationAwardExport($request))->download(sprintf('培养奖(%s).xls', Carbon::now()->format('YmdHisu')));
        }

        return $this->response->array(
            CommodityActivity::query()
                ->withTrashed()
                ->with(['statistics', 'skus', 'commodity' => function (BelongsTo $builder) {
                    $builder
                        ->withTrashed()
                        ->with(['supplier', 'category']);
                }])
                ->when(
                    $request->get('name') || $request->get('numbering') || $request->get('category') || $request->get('supplier_id'),
                    function (Builder $builder) use ($request) {
                        $builder
                            ->join('commodities', 'commodities.id', '=', 'commodity_activities.commodity_id')
                            ->when($request->get('name'), function ($builder, $name) {
                                $builder->where('commodities.name', 'like', "%$name%");
                            })
                            ->when($request->get('numbering'), function ($builder, $numbering) {
                                $builder->where('commodities.numbering', 'like', "%$numbering%");
                            })
                            ->when($request->get('category'), function ($builder, $category) {
                                $builder->where('category_id', $category);
                            })
                            ->when($request->get('supplier_id'), function ($builder, $supplierId) {
                                $builder->where('supplier_id', $supplierId);
                            });
                    })
                ->when($request->get('locking'), function (Builder $builder, $locking) {
                    $builder->where('locking', $locking);
                })
                ->whereHas('statistics')
                ->paginate()
        );
    }

    /**
     * 售后补偿
     * @param Request $request
     * @return mixed
     */
    public function getAfterSaleCompensation(Request $request)
    {
        if ($request->has('export')) {
            return (new AfterSaleCompensationExport($request))->download(sprintf('售后补偿(%s).xls', Carbon::now()->format('YmdHisu')));
        }

        return $this->response->array(
            CommodityActivity::query()
                ->withTrashed()
                ->with(['statistics', 'skus', 'commodity' => function (BelongsTo $builder) {
                    $builder
                        ->withTrashed()
                        ->with(['supplier', 'category']);
                }])
                ->when(
                    $request->get('name') || $request->get('numbering') || $request->get('category') || $request->get('supplier_id'),
                    function (Builder $builder) use ($request) {
                        $builder
                            ->join('commodities', 'commodities.id', '=', 'commodity_activities.commodity_id')
                            ->when($request->get('name'), function ($builder, $name) {
                                $builder->where('commodities.name', 'like', "%$name%");
                            })
                            ->when($request->get('numbering'), function ($builder, $numbering) {
                                $builder->where('commodities.numbering', 'like', "%$numbering%");
                            })
                            ->when($request->get('category'), function ($builder, $category) {
                                $builder->where('category_id', $category);
                            })
                            ->when($request->get('supplier_id'), function ($builder, $supplierId) {
                                $builder->where('supplier_id', $supplierId);
                            });
                    })
                ->when($request->get('locking'), function (Builder $builder, $locking) {
                    $builder->where('locking', $locking);
                })
                ->whereHas('statistics')
                ->paginate()
        );
    }

    /**
     * 财务明细
     * @param Request $request
     */
    public function financialDetails(Request $request)
    {
        if ($request->has('export')) {
            return (new FinanceDetailsExport($request))->download(sprintf('财务明细(%s).xls', Carbon::now()->format('YmdHisu')));
        }

        return $this->response->array(
            AgentRevenue::query()
                ->with(['source'])
                ->when($request->get('phone'), function (Builder $builder, $phone) {
                    $builder
                        ->join('agents', 'agents.id', '=', 'agent_revenues.agent_id')
                        ->where('agents.phone', 'like', "%$phone%");
                })
                ->when($request->get('type'), function (Builder $query, $type) {
                    $query->where('agent_revenues.type', $type);
                })
                ->when($request->get('created_at_begin'), function (Builder $query, $createdAtBegin) {
                    $query->where('agent_revenues.created_at', '>=', $createdAtBegin);
                })
                ->when($request->get('created_at_end'), function (Builder $query, $createdAtEnd) {
                    $query->where('agent_revenues.created_at', '<=', Carbon::parse($createdAtEnd)->endOfDay());
                })
                ->paginate(null, ['agent_revenues.*'])
        );
    }
}
